﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public delegate void ItemCount(Item itm);
public class inventoryScript : MonoBehaviour
{
    public event ItemCount itemCountEvent;
    private static inventoryScript instance;
    public static inventoryScript MyInstance
    {
        get
        {
            if (instance == null)
            {
                instance = FindObjectOfType<inventoryScript>();
            }
            return instance;
        }
    }
    [SerializeField]
    private bagButton[] baggButtons;
    [SerializeField]
    public Item[] items;
    private List<bag> bags = new List<bag>();
    public List<bag> MyBags { get => bags; }
    private slotScript fromSlot;
   
    public bool CanAddbag {
        get
        {
            return MyBags.Count < 5;
        }
    }

    public slotScript FromSlot {
        get => fromSlot;
        set
        {
            fromSlot = value;
            if(value != null)
            {
                fromSlot.MyIcon.color = new Color(0.5f,0.5f,0.5f,1);
            }
        }
        
    }

    bag bagg;

    public int MyEmptySlotCounter
    {
        get
        {
            int count = 0;
            foreach (bag n in MyBags)
            {
                count += n.MyBagScript.MyEmptySlotCounter;
            }
            return count;
        }
    }

    public int MyTotalSlots
    {
        get
        {
            int count = 0;
            foreach(bag n in MyBags)
            {
                count += n.MyBagScript.MySlots.Count;
            }
            return count;
        }
        
    }

    public int MyFullSlots
    {
        get
        {
            return MyTotalSlots - MyEmptySlotCounter;
        }
    }

    private void Awake()
    {

    } 
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.P))
        {
            bagg = (bag)Instantiate(items[0]);
            bagg.initialize(17);
            bagg.use();
        }
        if (Input.GetKeyDown(KeyCode.O))
        {
            CommonHealthPotion junkHealthPotion = (CommonHealthPotion)Instantiate(items[2]);
            AddItem(junkHealthPotion);
        }
        if (Input.GetKeyDown(KeyCode.H))
        {
            for (int i = 0; i < 1; i++)
            {
                CommonHealthPotion commonHealthPotion = (CommonHealthPotion)Instantiate(items[1]);
                AddItem(commonHealthPotion);
            }
            
            
            
            
        }
        if (Input.GetKeyDown(KeyCode.L))
        {
            bagg = (bag)Instantiate(items[0]);
            bagg.initialize(5);
            AddItem(bagg);
        }
        if (Input.GetKeyDown(KeyCode.K))
        {
            //Equipment equip = (Equipment)Instantiate(items[4]);
            for (int i = 0; i < items.Length; i++)
            {
                if (i > 2)
                {
                    AddItem((Equipment)Instantiate(items[i]));
                }
            }
            
        }
    }
    public void addBag (bag bagg)
    {
        foreach (bagButton bb in baggButtons)
        {
            if(bb.MyBagg == null)
            {
                bb.MyBagg = bagg;
                MyBags.Add(bagg);
                bagg.MyBagButton = bb;
                break;
            }
        }

    }
    public void addBag(bag bagg,bagButton bb)
    {
        MyBags.Add(bagg);
        bb.MyBagg = bagg;
    }
    public void addBag(bag bagg, int bagIndex)
    {
        bagg.ConnectBagScript();
        MyBags.Add(bagg);
        bagg.MyBagButton = baggButtons[bagIndex];
        bagg.MyBagButton.MyBagg = bagg;
        Debug.Log("inventoryScript/addBag: index of added bag is " + bagg.MyBagButton.MyBagId);
    }
    public void ToggleInv()
    {
        bool closed=MyBags.Find(x=>!x.MyBagScript.IsOpen);
        foreach(bag bagg in MyBags)
        {
            if (bagg.MyBagScript.IsOpen != closed)
            {
                bagg.MyBagScript.Toggle();
            }
        }
    }
    public bool AddItem(Item item)
    {
        if (item.StackSize > 0 && AddToStack(item))
        {
            return true;
        }
        else
        {
            return AddEmpty(item);
             
        }
    }
    private bool AddToStack(Item item)
    {
        foreach(bag bagg in MyBags)
        {
            foreach(slotScript slot in bagg.MyBagScript.MySlots)
            {
                if (slot.Stackable(item))
                {
                    ItemCountChange(item);
                   
                    return true;
                }
            }
        }
        return false;
    }

    public void AddToSpecificSlot(Item item, int slotIndex, int bagIndex)
    {
        bags[bagIndex].MyBagScript.MySlots[slotIndex].AddItem(item);
    }

    private bool AddEmpty(Item item)
    {
        foreach (bag bagg in MyBags)
        {
            if (bagg.MyBagScript.AddItem(item))
            {
                ItemCountChange(item);
                return true;
            }
            
        }
        return false;
    }
    public void deleteBagInv(bag bagg)
    {
        MyBags.Remove(bagg);   
        Destroy(bagg.MyBagScript.gameObject);
    }
    public void swapBags(bag frombag, bag destination)
    {
        int newsummaryslots = (MyEmptySlotCounter-frombag.Slots)+destination.Slots;
        if (newsummaryslots >= MyFullSlots)
        {
            List<Item> itms = frombag.MyBagScript.GetItems();
            deleteBagInv(frombag);
            destination.MyBagButton = frombag.MyBagButton;
            
            destination.use();

            foreach(Item itm in itms)
            {
                if(itm != destination)
                {
                    AddItem(itm);
                }
            }
            AddItem(frombag);
            
            handScript.MyInstance.Drop();
            frombag.MyBagButton = null;
            MyInstance.FromSlot = null;
        }
        
    }
    public Stack<IUsable> UsableItems(IUsable type)
    {
        Stack<IUsable> usables = new Stack<IUsable>();
        foreach(bag bagg in MyBags)
        {
            foreach(slotScript slot in bagg.MyBagScript.MySlots)
            {
                if (!slot.IsEmpty  && slot.MyItem.MyTitle==(type as Item).MyTitle)
                {
                    foreach(Item itm in slot.MyItems)
                    {
                        usables.Push(itm as IUsable);
                    }
                }
            }
        }
        return usables;
    }

    public IUsable UsableItem(string type)
    {
        Stack<IUsable> usables = new Stack<IUsable>();
        foreach (bag bagg in MyBags)
        {
            foreach (slotScript slot in bagg.MyBagScript.MySlots)
            {
                if (!slot.IsEmpty && slot.MyItem.MyTitle == type)
                {
                    return (slot.MyItem as IUsable);
                }
            }
        }
        return null;
    }

    public int GetItemCount(string itmName)
    {
        int count=0;
        foreach(bag bagggg in MyBags)
        {
            foreach(slotScript slot in bagggg.MyBagScript.MySlots)
            {
                if (!slot.IsEmpty && slot.MyItem.MyTitle == itmName)
                {
                    count+=slot.MyItems.Count;
                }
            }
        }
        return count;
    }

    public void ItemCountChange(Item itm)
    {
        if(itemCountEvent != null)
        {
            itemCountEvent.Invoke(itm);
        }
    }
    public List<slotScript> GetFullSlots()
    {
        List<slotScript> fullSlots = new List<slotScript>();
        foreach(bag tempBag in MyBags)
        {
            Debug.Log("Bagindex " + tempBag.MyBagButton.MyBagId);
            foreach(slotScript tempSlot in tempBag.MyBagScript.MySlots)
            {
                if (!tempSlot.IsEmpty)
                {
                    tempSlot.MyBag.MyBagIndex = tempBag.MyBagButton.MyBagId;
                    fullSlots.Add(tempSlot);
                    Debug.Log("fullSlot in slot " + tempSlot.MySlotIndex+" in bag "+tempSlot.MyBag.MyBagIndex);
                }
            }
        }
        return fullSlots;
    }
}                                                                    